package ChannelTutorial.Demo05;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * Demo05 - Channel 常用操作实战 - 服务端
 * 
 * 简单的 Echo 服务端，用于客户端测试各种 Channel 操作
 */
@Slf4j
public class Server {

    public static void main(String[] args) {
        log.info("=== Channel 常用操作实战 - 服务端 ===\n");
        
        new Thread(() -> {
            try {
                startServer();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

    /**
     * 启动服务端
     */
    private static void startServer() throws Exception {
        EventLoopGroup boss = new NioEventLoopGroup(1);
        EventLoopGroup worker = new NioEventLoopGroup();
        
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(boss, worker)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) {
                        ch.pipeline().addLast(new EchoServerHandler());
                    }
                });
            
            ChannelFuture bindFuture = serverBootstrap.bind(8080).sync();
            log.info("[服务端] 已启动，监听端口 8080\n");
            log.info("[服务端] 请运行 Client.java 客户端进行测试\n");
            
            bindFuture.channel().closeFuture().sync();
            
        } finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }

    /**
     * 简单的服务端处理器
     */
    @Slf4j
    static class EchoServerHandler extends ChannelInboundHandlerAdapter {
        
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf buf = (ByteBuf) msg;
            String data = buf.toString(CharsetUtil.UTF_8);
            log.info("[服务端] 收到: {}", data.trim());
            
            // 回显数据
            ctx.writeAndFlush(msg);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            log.error("[服务端] 异常", cause);
            ctx.close();
        }
    }
}

